﻿#ifndef EAGLESDKDEMO_H
#define EAGLESDKDEMO_H

#include <QtWidgets/QMainWindow>
#include <QThread>
#include <QVector>
#include <QMap>
#include <memory>
#include <QComboBox>
#include "ui_EagleMainFrame.h"
#include "ui_simuPlayDlg.h"
#include "ui_simuCtrlInfoWgt.h"

// #define STATIC_LIB

//#define _NODEVICE


class BusyCursor
{
public:

	BusyCursor()
	{
		QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));  // 鼠标等待 [11/7/2016 ejitec]
		QCoreApplication::processEvents();
	}

	~BusyCursor()
	{
		QApplication::restoreOverrideCursor();
	}
};


typedef enum
{
	EagleControlStart = 0,
	EagleControlContinue,
}EagleControlStatusType;

typedef enum
{
	RECORD_SECOND = 0,
	RECORD_FNM
}RECORD_TYPE;


class CursorWait;
class QDisPlayWidget;
class BaseDisParentWnd;
class QScrollArea;
class CEagleDeviceMgr;
class EaglePostEventManager;
class QHBoxLayout;

// 不同状态加载不同的ico 和 文字提示 [4/1/2017 ejitec]
typedef struct tagDoubleAction
{
	QVector<QIcon> m_icos;
	QStringList m_texts;
	QStringList m_tooltips;
	bool m_bNormal;
	tagDoubleAction()
		:m_bNormal(true)
	{
	}

	void clear()
	{
		m_icos.clear();
		m_texts.clear();
		m_tooltips.clear();
	}

	QIcon& icon(bool bNormal = true)
	{
		m_bNormal = bNormal;

		return m_icos[m_bNormal ? 0 : 1];
	}

	QString text()
	{
		return m_texts[m_bNormal ? 0 : 1];
	}

	QString toolTip()
	{
		return m_tooltips[m_bNormal ? 0 : 1];
	}

} TDoubleAction;

typedef enum 
{
	E_INDEX_PREVIEW,
	E_INDEX_RECPLAY,
	E_INDEX_RECORD,
	E_INDEX_PAUSE,
	E_INDEX_RECEXP,


}E_ICON_INDEX;

// 仿真 Dlg
class CSimulaPlayDlg :public QDialog
{
	Q_OBJECT

public:

	CSimulaPlayDlg(QVector<TDevWithCCDInfo*>& devList,QWidget* parent);
	~CSimulaPlayDlg();
	QDisPlayWidget* getPlayWndBy(int devID, int ccdID);
	void setCtrlButtonStatus(bool bPlayOK);
	void checkIsAllStop();

	void toFull(QDisPlayWidget* curWnd,bool bFull);

	void toNormal(BaseDisParentWnd* curWnd);

protected slots:

	void on_buttonStartExportOnButtonClick();
	void on_buttonStopExportOnButtonClick();
	void on_tPrevSimullateClicked();
	void on_tNextSimullateClicked();
	void on_tPlayPauseSimullateClicked();

protected:

	void createPlayWnds();
	void destoryPlayWnds();
	virtual void closeEvent(QCloseEvent *);

private:
	Ui::simuPlayDlg ui;
	std::vector<int> _checkDevs;
	QVector<BaseDisParentWnd*> m_BaseDisWnds;
	QVector<QDisPlayWidget*> m_DisplayWnds;    // 所有的显示窗口
	QVector<TDevWithCCDInfo*>&  _tDevsInfo;
	QHBoxLayout* _disPlayHL;
	bool m_bPause;
};

class CSimuPlayInfoWgt :public QWidget
{
	Q_OBJECT

public:
	CSimuPlayInfoWgt(int ndev, QString title, QWidget* parent = NULL);
	MessageCmd* PrepareStartExp();
	bool IsStop()
	{
		return !ui.btn_stop->isEnabled();
	}

	bool toStartSimuPlay();

protected:
	void EnableSelect(bool bEnable, int TotalFrame, int column, int line, int color_depth, int task_index, int record_index);
	void AppendRecord(EagleData_Record_Id* record_id);
	int is_camlink_export_param_valid(char clock_hz, int column, int line, int frame_taps, int frame_rate);
	void GetConfig(long &start_frame, long &stop_frame, long &interval, unsigned short &frame_rate, unsigned char& frame_taps, unsigned char& clock_hz, unsigned short& column, unsigned short& line, unsigned short& color_depth);

public:
	
	int _column;
	int _line;
	int _color_depth;
	int _task_index;
	int _record_index;

public slots:

	void on_StartSimuPlay();
	void on_StopSimuPlay();

private:
	Ui::simuCtrlInfoWgt ui;
	std::vector<int> _checkDevs;
	int _devID;
	QString _PanelNam;
	CSimulaPlayDlg* _parent;
};


class EagleMainFrame : public QMainWindow
{
	Q_OBJECT

public:
	friend CursorWait;
	friend CEagleDeviceMgr;

	EagleMainFrame(QWidget *parent = 0);
	~EagleMainFrame();
	QVector<QDisPlayWidget*>& getPlayWnds()
	{
		return m_DisplayWnds;
	}

	void toFull(bool bfull);

	void toNormal(BaseDisParentWnd* curWnd);

	void reLayOutWnds(QWidget* curWnd);

	QDisPlayWidget* MainWidget() const { return m_mainWidget; }

	QVector<TDevWithCCDInfo*>& DevList() { return m_vDevList; }


	void doWorkInUi(signalFun pf)  //- 有线使用方法 二
	{
		TCbJob tJob;
		tJob.m_eType = E_JOBTYPE_FRESHUI;
		tJob.m_fWork = pf;
		// 界面执行
		QMetaObject::invokeMethod(this, "on_UiOP", Qt::BlockingQueuedConnection, Q_ARG(TCbJob, tJob));
	}

	void doWorkInUi_2(UIEventCallbackType pf)
	{
		m_UiTask.Post(pf);
	}

	QDisPlayWidget* getPlayWndBy(int devID, int ccdID);

	QVector<EagleData_Record_Id*>& getRecList()
	{
		return m_vRecList;
	}

protected:

	bool Init();

	void Init_UI();

	void scanNetWork();

	void createPlayWnds();

	void destoryPlayWnds();
	
	void postMessageBy(int devID, int ccdID, MessageCmd* ptCmd);

	virtual bool eventFilter(QObject *watched, QEvent *event);

	virtual void closeEvent(QCloseEvent *event);

	void setDevTree();
	void setRecTree();
	void fetchDevList();
	void fetchRecList();
	void clearTree(QTreeWidget* ptTree);

	void threadFun_remout(std::shared_ptr<EagleData_Record> spRecord = nullptr);
	void remountByDevs(vector<int>& devs);
	void remountBySelRecords();

	void doSingleExp(std::shared_ptr<EagleData_Record> spRec);

	void doBatchExp(BatchExportContext& ctx);

	void ConnectWaitThread();

	void Wait(QString stInfo);
	void FinishWait();
	void WaitDisplayModuleDoneThread(int msTime);

	void RefetchRecordListThread(bool show_info = true);

	bool IsDisplayPanelInDisplaying(bool need_delay);
	void ExportWaitThread(QString wait_msg);
	int StartDevicePreviewThread(int device_id);
	void StartPreviewThread();
	void StopPreviewThread(bool judge_display_status);
	int StopDevicePreviewThread(int device_id);
	void SuspendRecordThread(bool bSuspend, int rec_fnm);
	int SuspendDeviceRecordThread(int device_id, bool bSuspend, int rec_fnm);
	// 记录操作 [2/15/2017 ejitec]
	void StartRecordThread(int capture_frame_num, int capture_time, int capture_frame_interval);
	int StartDeviceRecordThread(int device_id, int capture_frame_num, int capture_time, int capture_frame_interval);
	void StopRecordThread();
	int StopDeviceRecordThread(int device_id, bool displaying);

	void UpdateAllTools(ECaptureStatusType current_status, bool need_delay);

	void  StartDisplayModuleThread();
	
	void StopDisplayModule();

	void FormatDiskThread();

protected slots:
	// 仿真 [11/24/2017 xystar]
	void on_SimuMenuDataImport();
	void on_SimuMenuPaly();

	// end [11/24/2017 xystar]
	void on_timeToFreshStat();
	void on_setControlNICs();
	void on_WorkFinish(TCbJob tCb);
	void on_TShowSysInfo();
	void on_TRecPlay();
	void on_TExport();
	void on_TPreview();
	void on_TRecord();
	void on_TPauseRec();
	void on_TDel();

	// 数据菜单 [12/1/2016 ejitec]
	void on_DataMenuRescanRecList();
	void on_DataMenuRename();

	// system
	void on_SysMenuFormatDisk();
	void on_SysMenutoFactory();

	// 自检菜单 [12/1/2016 ejitec]
	void on_CheckData();
	void on_CheckRecord();

	void on_netWorkChange();

	void on_UiOP(TCbJob tCb)  // 
	{
		if (tCb.m_fWork)
		{
			tCb.m_fWork();
		}
	}

	// 

signals:
	//virtual QPaintEngine * paintEngine() const;
	void evt_netWorkChange();
	void evt_recListChange();
	void evt_rawLog(int nType, const QString& strMsg);
	void evt_workFinish(TCbJob tCb);
private:
	
	Ui::EagleMainFrame ui;
	EaglePostEventManager m_UiTask;  // 非UI线程中 UI线程管理类 刷新界面 
	QMap<int, TDoubleAction> m_vDoubleIons;  // 针对多状态下的 菜单和工具栏
	Worker m_cWorker;
	int m_nCameraCnt;
	QVector<TDevWithCCDInfo*> m_vDevList;
	QVector<EagleData_Record_Id*> m_vRecList;
	EvtThreadHandler* m_ptJobHander;
	bool m_bFullScreen;
	QVector<BaseDisParentWnd*> m_BaseDisWnds;
	QVector<QDisPlayWidget*> m_DisplayWnds;    // 所有的显示窗口
	QVector<QDisPlayWidget*> m_CurPlayWnds;   // 录像播放的所有窗口
	QDisPlayWidget* m_mainWidget;

	// for debug
	bool m_bRecPlay;

	std::mutex m_recTreeLock;
	// 工具栏2个单位和数值控件 [11/8/2016 ejitec]
	QComboBox* _toolcmb_dataNum;
	QComboBox* _toolcmb_dataUnit;
	// 播放窗口布局
	QScrollArea* _smallWndScroll;
	QHBoxLayout* _hLayoutOut;
	QVBoxLayout *_vLayoutSmallWnds;
	QWidget* _smallWndWidget;

	// 窗口状态 [12/5/2016 ejitec]
	EagleControlStatusType record_status;
	EagleControlStatusType record_suspend_status;
	EagleControlStatusType replay_status;
	RECORD_TYPE            record_type;
	ECaptureStatusType cap_status_expected;  // 操作状态
	QTimer* _timer;
};


class CursorWait
{
public:

	CursorWait(QString strText)
	{
		g_theApp->Wait(strText);
	}

	~CursorWait()
	{
		g_theApp->FinishWait();
	}
};



#endif // EAGLESDKDEMO_H
